/*
打印
 */
import 'dart:io';

import 'package:reabampos/src/reabam/operation/bean/h5_print.dart';
import 'package:reabampos/src/reabam/operation/rb_api.dart';
import 'package:reabampos/src/reabam/operation/rb_config.dart';
import 'package:reabampos/src/reabam/ui/pagestate_main_webview.dart';
import 'package:reabampos/src/reabam/ui/setting/bean/bean_appoint_printer_scene.dart';
import 'package:reabampos/src/reabam/utils/rb_aliyun_log.dart';
import 'package:xsdk_flutter/xsdk/utils/x_utils_aliyun_log.dart';
import 'package:xsdk_flutter/xsdk/xsdk_flutter_package.dart';
import 'package:xsdk_flutter_plugin/xsdk_flutter_plugin.dart';

abstract class SupportControlDevices {
  static XQueue? msgQueue;

  //1.初始化
  static void init(XPageState statePage) {
    //初始化h5打印通知队列
    _initH5PrintMsgQueue(statePage);
    //蓝牙BLE设备监听
    _initBleDeviceListener(statePage);
    //Socket设备监听
    _initSocketDeviceListener(statePage);
  }

//////////////////////////////////////////////

  static List<XBaseDevice> bluetoothPrinters = [];
  static List<XBaseDevice> socketPrinters_ip = [];
  static List<XBaseDevice> cloudPrinters = [];
  static List<XBaseDevice> usbPrinters = [];
  static XBaseDevice? bluetoothWeigher;
  static XBaseDevice? usbWeigher;
  //叫号屏
  static XBaseDevice? socketTV;
  static XBaseDevice? clientSocketPrinter;

  //是否启用多端打印
  static bool isEnableServerClientSocketPrint = false;
  //是否多端打印服务端
  static bool isServerSocketPrinter = false;

  //设备设置指定打印机
  static List<BeanAppointPrinterScene> appointPrinterSettingList = [];

  //1.初始化或重新初始化(外界)
  static void initAllDevicesNoteSetting() {
    try {
      socketTV = null;
      clientSocketPrinter = null;
      usbWeigher = null;
      bluetoothWeigher = null;
      bluetoothPrinters.clear();
      socketPrinters_ip.clear();
      cloudPrinters.clear();
      usbPrinters.clear();
      appointPrinterSettingList.clear();

      //蓝牙
      for (XBaseDevice device in XBluetoothBLEUtils.bluetoothBLEDeviceList) {
        if (RBConfigs.BluetoothPrinter == device.customType) {
          bluetoothPrinters.add(device);
        } else if (RBConfigs.BluetoothWeigher == device.customType) {
          bluetoothWeigher = device;
        }
      }

      //网络
      for (XBaseDevice device in XSocketUtils.socketDeviceList) {
        if (RBConfigs.SocketTV == device.customType) {
          socketTV = device;
        } else if (RBConfigs.IPPrinter == device.customType) {
          socketPrinters_ip.add(device);
        } else if (RBConfigs.ClientSocketPrinter == device.customType) {
          clientSocketPrinter = device;
        }
      }

      //快麦云打印
      for (XBaseDevice device in XRemoteDeviceUtils.remoteDeviceList) {
        cloudPrinters.add(device);
      }

      //usb
      for (XBaseDevice device in XUsbUtils.usbDeviceList) {
        if (RBConfigs.USBPrinter == device.customType) {
          usbPrinters.add(device);
        }
      }

      //多端打印
      isEnableServerClientSocketPrint = false;
      isServerSocketPrinter = false;
      //
      String companyId =
          XSharePreferencesUtils.getString(RBConfigs.SP_companyId);
      bool isUseServerClientSocketPrinter = XSharePreferencesUtils.getBool(
          '${RBConfigs.SP_isUseServerClientSocketPrinter}$companyId');
      String currentSocketServerOrClient = XSharePreferencesUtils.getString(
          '${RBConfigs.SP_currentServerOrClientSoscketPrinter}$companyId');
      if (isUseServerClientSocketPrinter) {
        if (currentSocketServerOrClient == '主设备') {
          isEnableServerClientSocketPrint = true;
          isServerSocketPrinter = true;
        } else if (currentSocketServerOrClient == '子设备') {
          isEnableServerClientSocketPrint = true;
        }
      }

      //
      if (isEnableServerClientSocketPrint) {
        String json_appointPrinterSettingList = '';
        if (isServerSocketPrinter) {
          json_appointPrinterSettingList = XSharePreferencesUtils.getString(
              '${RBConfigs.SP_ServerSocket_Appoint_printer}$companyId');
        } else {
          json_appointPrinterSettingList = XSharePreferencesUtils.getString(
              '${RBConfigs.SP_ClientSocket_Appoint_printer}$companyId');
        }

        if (!XStringUtils.isEmpty(json_appointPrinterSettingList)) {
          List<dynamic> ll =
              XJsonUtils.json2List(json_appointPrinterSettingList);
          for (dynamic item in ll) {
            appointPrinterSettingList
                .add(BeanAppointPrinterScene.fromJson(item));
          }
        }
      }
    } catch (e) {
      XLogUtils.printLog('---initAllDevicesNoteSetting error: $e');
    }
  }

  //收到h5通知打印ok
  static void needPrint(XPageState statePage, dynamic data) {
    //注意: 如果收不到h5通知,则检测门店是否开启在线打印
    try {
      BeanH5PrintInfo beanH5PrintInfo;
      if (data is String) {
        beanH5PrintInfo = BeanH5PrintInfo.fromJson(XJsonUtils.json2Map(data));
      } else {
        beanH5PrintInfo = BeanH5PrintInfo.fromJson(data);
      }

      XLogUtils.printLog(
          '---收到h5通知打印needPrint, kmPrintH5Id=${beanH5PrintInfo.kmPrintH5Id}, 设备场景printerTag:${beanH5PrintInfo.printerTag}, 设备序号printIndex:${beanH5PrintInfo.printIndex}, beanH5PrintInfo=${XJsonUtils.obj2Json(beanH5PrintInfo)}');

      if (XFlutterUtils.isiOS() || XFlutterUtils.isMacOS()) {
        //苏芙特丽,打印乱码,快麦建议间隔1s
        sleep(const Duration(seconds: 1));
      } else {
        sleep(const Duration(milliseconds: 100));
      }

      //日志
      XAliyunLogUtils.sendLog(
          RBAliyunLogUtils.getAliyunLogKey_Print(beanH5PrintInfo.orderNo),
          '收到h5通知打印: 设备场景printerTag=${beanH5PrintInfo.printerTag}, 设备序号printIndex=${beanH5PrintInfo.printIndex}, kmPrintH5Id=${beanH5PrintInfo.kmPrintH5Id}, data= $data');

      // hyl 2021.11.25 不需要本地做重打漏打机制,交给服务端
      String createTime = XDateUtils.getCurrentTime_String(
          format: XDateUtils.formatTimeDefault2);
      String msgId =
          '${beanH5PrintInfo.orderNo}_${beanH5PrintInfo.kmPrintH5Id ?? XDateUtils.getCurrentTime_ms()}';

      beanH5PrintInfo.kmItemsId ??= '10';
      beanH5PrintInfo.kmUserId ??= '13826056942';
      beanH5PrintInfo.kmPrintH5Id ??= 'kmPrintH5Id=null';

      XBaseQueueMessage printMsg = XBaseQueueMessage(
        msgId: msgId,
        isSaveToQueueSrcMsgList: true,
        createTime: createTime,
        message: beanH5PrintInfo.printDataJson ?? '',
        orderId: beanH5PrintInfo.orderId,
        orderNo: beanH5PrintInfo.orderNo,
        orderType: '${beanH5PrintInfo.orderType}',
        templateId: beanH5PrintInfo.kmId,
        templateType: beanH5PrintInfo.kmCmdType,
        otherParams: [
          '${beanH5PrintInfo.kmItemsId}',
          '${beanH5PrintInfo.kmUserId}',
          '${beanH5PrintInfo.kmPrintH5Id}',
        ],
      );

      //打印场景
      if (beanH5PrintInfo.printerTag == null) {
        //日志
        XAliyunLogUtils.sendLog(
            RBAliyunLogUtils.getAliyunLogKey_Print(beanH5PrintInfo.orderNo),
            'h5打印内容没有设置打印场景');
        //通知h5,-2没有找到打印机
        _printResult_callback_H5_or_clientSocket(
            statePage, false, '没有设置打印场景', printMsg);
        return;
      }

      XBaseDeviceScene deviceScene =
          XBaseDeviceScene(id: '${beanH5PrintInfo.printerTag}');
      printMsg.deviceScene = deviceScene;

      //判断是否有蓝牙打印设备
      if (RBConfigs.isShangMiDevice &&
          RBConfigs.isUserShangMiPrint &&
          '${beanH5PrintInfo.printerTag}' != "4") {
        //商米设备,小票打印,不需要判断 ok  保存到队列
        XLogUtils.printLog('---商米设备,小票打印,不需要判断 ok');

        msgQueue?.addNewMsgToQueueForWaitQueueAutoHandle(printMsg);
        return;
      }

      if (bluetoothPrinters.isEmpty &&
          usbPrinters.isEmpty &&
          socketPrinters_ip.isEmpty &&
          cloudPrinters.isEmpty &&
          (!isEnableServerClientSocketPrint || isServerSocketPrinter)) {
        XLogUtils.printLog('---设备没有设置打印机!');
        //阿里云日志
        XAliyunLogUtils.sendLog(
            RBAliyunLogUtils.getAliyunLogKey_Print(beanH5PrintInfo.orderNo),
            "设备没有设置打印机!");
        statePage.toast("请先设置打印机");
        //通知h5,-2没有找到打印机
        _printResult_callback_H5_or_clientSocket(
            statePage, false, '没有设置打印机', printMsg);
        return;
      }

      //是否多端子设备打印
      if (isEnableServerClientSocketPrint && !isServerSocketPrinter) {
        //阿里云日志
        XAliyunLogUtils.sendLog(
            RBAliyunLogUtils.getAliyunLogKey_Print(beanH5PrintInfo.orderNo),
            "开启多端打印,子设备...");
      }

      //打印序号
      if (beanH5PrintInfo.printIndex != null) {
        //以h5指定打印机序号优先
        printMsg.deviceSerialNumber = '${beanH5PrintInfo.printIndex}';
      }

      //h5没有指定打印机序号
      if (XStringUtils.isEmpty(printMsg.deviceSerialNumber)) {
        //开启多端打印,以指定打印机设置为准
        if (isEnableServerClientSocketPrint &&
            appointPrinterSettingList.isNotEmpty) {
          List<String> deviceSerialNumbers = [];
          for (BeanAppointPrinterScene appointPrinterScene
              in appointPrinterSettingList) {
            if ('${beanH5PrintInfo.printerTag}' == appointPrinterScene.id) {
              List<BeanAppointPrinterIndex> printerIndexs =
                  appointPrinterScene.printerIndexs;
              for (BeanAppointPrinterIndex appointPrinterIndex
                  in printerIndexs) {
                if (appointPrinterIndex.isUserSelect) {
                  deviceSerialNumbers.add(appointPrinterIndex.id);
                }
              }
              break;
            }
          }

          //拆分多条打印
          if (deviceSerialNumbers.length != 0) {
            XLogUtils.printLog(
                '---多端打印,指定设置打印机序号,deviceSerialNumbers=${deviceSerialNumbers.length},${XJsonUtils.obj2Json(deviceSerialNumbers)}');
            //阿里云日志
            XAliyunLogUtils.sendLog(
                RBAliyunLogUtils.getAliyunLogKey_Print(beanH5PrintInfo.orderNo),
                "---多端打印,指定设置打印机序号,deviceSerialNumbers=${XJsonUtils.obj2Json(deviceSerialNumbers)}");

            String mJson = XJsonUtils.obj2Json(printMsg);
            for (int i = 0; i < deviceSerialNumbers.length; i++) {
              XLogUtils.printLog(
                  '---多端打印,for指定设置打印机序号,i=$i,${deviceSerialNumbers[i]}');
              XBaseQueueMessage nMsg =
                  XBaseQueueMessage.fromJson(XJsonUtils.json2Map(mJson));
              nMsg.msgId = '拆分${i}_${nMsg.msgId}';
              nMsg.deviceSerialNumber = deviceSerialNumbers[i];
              msgQueue?.addNewMsgToQueueForWaitQueueAutoHandle(nMsg);
            }
            return;
          }
        }
      }

      //默认1号设备
      if (XStringUtils.isEmpty(printMsg.deviceSerialNumber)) {
        printMsg.deviceSerialNumber = '1';
      }
      //
      msgQueue?.addNewMsgToQueueForWaitQueueAutoHandle(printMsg);
    } catch (e) {
      XAliyunLogUtils.sendLog(
          RBAliyunLogUtils.getAliyunLogKey_trycache('needPrint'), '$e');
      XLogUtils.printLog('$e');
    }
  }

  //初始化h5打印通知队列
  static void _initH5PrintMsgQueue(XPageState statePage) {
    if (msgQueue != null) {
      msgQueue?.xRelease();
      msgQueue = null;
    }

    msgQueue = XQueue(
        queueName: 'H5PrintMsgQueue',
        isConcurrentMode: true,
        notifyHandleMsg: (XBaseQueueMessage msg) {
          //子设备以主设备的打印配置为准
          if (isEnableServerClientSocketPrint && !isServerSocketPrinter) {
            //开启多端打印,子设备发送打印消息到主设备
            if (clientSocketPrinter != null &&
                clientSocketPrinter!.isConnected) {
              //
              XLogUtils.printLog('---多端打印,子设备正在发送打印,msg=${msg.msgId}');
              //阿里云日志
              XAliyunLogUtils.sendLog(
                  RBAliyunLogUtils.getAliyunLogKey_Print(msg.orderNo),
                  '---多端打印,子设备正在发送打印,msg=${msg.msgId}');
              //
              Map<String, dynamic> socketMap = {};
              socketMap['type'] = 'XClientSocketPrint';
              socketMap['data'] = msg;
              //
              XBaseQueueMessage socketMsg = XBaseQueueMessage(
                msgId: msg.msgId,
                message: socketMap,
                ip: clientSocketPrinter!.ip,
                port: clientSocketPrinter!.port,
              );
              XSocketUtils.sendMsgToQueue(socketMsg);
            } else {
              XLogUtils.printLog('---多端打印,子设备已断开连接,发送打印失败');
              //阿里云日志
              XAliyunLogUtils.sendLog(
                  RBAliyunLogUtils.getAliyunLogKey_Print(msg.orderNo),
                  '---多端打印,子设备已断开连接,发送打印失败');
              //打印结果通知h5
              _printResult_callback_H5_or_clientSocket(
                  statePage, false, clientSocketPrinter?.ip ?? '', msg);
            }

            return;
          }

          //1.优先使用云打印
          bool isUseKuaimaiCloudPrint = _use_cloud_print(statePage, msg);
          if (isUseKuaimaiCloudPrint) {
            return;
          }
          //2.使用快麦api在线模板生成打印命令,本地连接蓝牙,网络,usb设备打印
          _use_ble_socket_usb_print(statePage, msg);
        },
        notifyTempMsgQueueIdleAndMsgQueueHasItem: () {},
        notifyHandleHeartbeat: () {
          //没有心跳包,不需要处理
        });
    msgQueue!.init();
  }

  //1.使用云打印
  static bool _use_cloud_print(
      XPageState statePage, XBaseQueueMessage tempMsg) {
    //判断是否存在指定打印机序号
    String? deviceSerialNumber = tempMsg.deviceSerialNumber;
    //hyl 2023.10.28 优化, 必定存在打印机序号,默认1,
    XBaseDevice? appointPrinter;
    for (XBaseDevice deviceItem in cloudPrinters) {
      //判断设备序号
      if (deviceSerialNumber == deviceItem.serialNumber) {
        List<XBaseDeviceScene>? scenes = deviceItem.scenes;
        if (scenes != null) {
          for (XBaseDeviceScene scene in scenes) {
            //判断设备场景
            if (scene == tempMsg.deviceScene) {
              appointPrinter = deviceItem;
              //
              break;
            }
          }
          if (appointPrinter != null) {
            break;
          }
        }
      }
    }

    //
    if (appointPrinter != null) {
      XLogUtils.printLog("---找到指定云打印机");

      int templateType = 0;
      if (XStringUtils.equalsIgnoreCase(
          'getTicketData', tempMsg.templateType)) {
        templateType = 0; //小票
      } else {
        templateType = 1; //标签
      }

      if ('快麦' == appointPrinter.brand) {
        RBBaseApi.useKuaimaiCloudDevicePrint(
            requestId: tempMsg.msgId,
            dataSet: XJsonUtils.json2Map(tempMsg.message),
            sn: appointPrinter.deviceUUID,
            templateId: tempMsg.templateId,
            type: templateType,
            succeed: (response, Map<String, dynamic> responseMap,
                Map<String, dynamic> headers_response) {
              XAliyunLogUtils.sendLog(
                  RBAliyunLogUtils.getAliyunLogKey_Print(tempMsg.orderNo),
                  '---云打印,快麦api,succeed,response=${XJsonUtils.obj2Json(responseMap)}');

              //处理消息队列
              msgQueue?.handleSucceedMessageAndUnLockTempMessageQueue(
                  responseMap['data']?['requestId']);
              //打印结果通知
              _printResult_callback_H5_or_clientSocket(
                  statePage, true, '云打印:${appointPrinter!.brand}', tempMsg);
            },
            failed: (String code, String msg) {
              //处理消息队列
              XAliyunLogUtils.sendLog(
                  RBAliyunLogUtils.getAliyunLogKey_Print(tempMsg.orderNo),
                  '---云打印,快麦api,failed,code=$code,msg=$msg');

              msgQueue?.handleFailedMessageAndUnlockTempMessageQueue(
                  tempMsg.msgId, msg);
              //打印结果通知
              _printResult_callback_H5_or_clientSocket(
                  statePage, false, '云打印:${appointPrinter!.brand}', tempMsg);
            });
      } else {
        //其他品牌调用api打印...
        //处理消息队列
        XAliyunLogUtils.sendLog(
            RBAliyunLogUtils.getAliyunLogKey_Print(tempMsg.orderNo),
            '---云打印,其他品牌没有适配');

        msgQueue?.handleFailedMessageAndUnlockTempMessageQueue(
            tempMsg.msgId, '使用云打印失败,没有配置该品牌${appointPrinter.brand}云打印api');
        //打印结果通知
        _printResult_callback_H5_or_clientSocket(
            statePage, false, '云打印:${appointPrinter.brand}', tempMsg);
      }

      return true;
    }

    //没有可用的云打印
    return false;
  }

  //2.使用蓝牙,socket,usb打印
  static void _use_ble_socket_usb_print(
      XPageState statePage, XBaseQueueMessage msg) {
    //请求快麦打印
    XLogUtils.printLog(
        '---发起请求快麦api,orderNo=${msg.orderNo}, msgId=${msg.msgId}, data=${msg.message}');
    //日志
    XAliyunLogUtils.sendLog(RBAliyunLogUtils.getAliyunLogKey_Print(msg.orderNo),
        '---发起请求快麦api, msgId=${msg.msgId}, 类型=${msg.templateType} data=${msg.message}');

    if (XStringUtils.equalsIgnoreCase('getTicketData', msg.templateType)) {
      //小票打印ok
      XLogUtils.printLog('---快麦小票打印');
      //
      RBBaseApi.kmXiaopiaoPrint(
          templateId: msg.templateId ?? '',
          renderData: msg.message ?? '',
          requestId: msg.msgId ?? '',
          succeed: (dynamic response1, Map<String, dynamic> responseMap,
              Map<String, dynamic> headersResponse) {
            // Future((){
            // });

            //
            XLogUtils.printLog(
                '---快麦小票打印api请求返回成功! msgId=${responseMap['requestId']}, response=${responseMap['data']}');
            //阿里云日志
            XAliyunLogUtils.sendLog(
                RBAliyunLogUtils.getAliyunLogKey_Print(msg.orderNo),
                '---快麦小票打印api请求成功,返回: msgId=${responseMap['requestId']}, response=${responseMap['data']}');
            //成功,处理消息队列,并获得留底消息
            XBaseQueueMessage? msgSrc =
                msgQueue?.handleSucceedMessageAndUnLockTempMessageQueue(
                    responseMap['requestId']);

            if (msgSrc != null) {
              // hyl 2021.11.25 打印机队列不需要留底
              msgSrc.isSaveToQueueSrcMsgList = false;
              XLogUtils.printLog('---找到对应的消息,处理快麦小票api响应');
              //阿里云日志
              XAliyunLogUtils.sendLog(
                  RBAliyunLogUtils.getAliyunLogKey_Print(msg.orderNo),
                  '---找到对应的消息,处理快麦小票api响应');
              //处理快麦小票api响应
              _handleKMResponse_xiaopiao(statePage, responseMap, msgSrc);
            } else {
              XLogUtils.printLog(
                  '---找不到对应的消息,返回的requestId= ${responseMap['requestId']} 不能匹配');
              //阿里云日志
              XAliyunLogUtils.sendLog(
                  RBAliyunLogUtils.getAliyunLogKey_Print(msg.orderNo),
                  '---找不到对应的原始消息,返回的requestId= ${responseMap['requestId']} 不能匹配');
              //这里找不到原始消息,无法通知h5,等h5超时再重发
            }
          },
          failed: (String code, String errorMsg) {
            XLogUtils.printLog('---快麦小票请求api失败!');
            statePage.toast('快麦小票请求api失败:$errorMsg');
            //阿里云日志
            XAliyunLogUtils.sendLog(
                RBAliyunLogUtils.getAliyunLogKey_Print(msg.orderNo),
                '---快麦小票打印api请求失败! msgId=${msg.msgId}, errorMsg=$errorMsg');
            //
            msgQueue?.handleFailedMessageAndUnlockTempMessageQueue(
                msg.msgId, errorMsg);
            //通知h5
            _printResult_callback_H5_or_clientSocket(
                statePage, false, '快麦小票请求api失败:$errorMsg', msg);
          });
    } else {
      //标签打印ok
      XLogUtils.printLog('---快麦标签打印');
      RBBaseApi.kmTSPLPrint(
          templateId: msg.templateId ?? '',
          renderData: msg.message ?? '',
          requestId: msg.msgId ?? '',
          succeed: (dynamic response1, Map<String, dynamic> responseMap,
              Map<String, dynamic> headersResponse) {
            // Future((){
            // });

            XLogUtils.printLog(
                '---快麦标签打印api请求成功,返回: msgId=${responseMap['requestId']}, response=${responseMap['data']}');
            //阿里云日志
            XAliyunLogUtils.sendLog(
                RBAliyunLogUtils.getAliyunLogKey_Print(msg.orderNo),
                '---快麦标签打印api请求成功,返回: msgId=${responseMap['requestId']}, response=${responseMap['data']}');
            //成功,处理消息队列,并获得留底消息
            XBaseQueueMessage? msgSrc =
                msgQueue?.handleSucceedMessageAndUnLockTempMessageQueue(
                    responseMap['requestId']);

            if (msgSrc != null) {
              // hyl 2021.11.25 打印机队列不需要留底
              msgSrc.isSaveToQueueSrcMsgList = false;
              XLogUtils.printLog('---找到对应的消息,处理快麦标签api响应');
              //阿里云日志
              XAliyunLogUtils.sendLog(
                  RBAliyunLogUtils.getAliyunLogKey_Print(msg.orderNo),
                  '---找到对应的消息,处理快麦标签api响应');
              //处理快麦标签api响应
              _handleKMResponse_biaoqian(statePage, responseMap, msgSrc);
            } else {
              XLogUtils.printLog(
                  '---找不到对应的消息,返回的requestId= ${responseMap['requestId']} 不能匹配');
              //阿里云日志
              XAliyunLogUtils.sendLog(
                  RBAliyunLogUtils.getAliyunLogKey_Print(msg.orderNo),
                  '---找不到对应的消息,返回的requestId= ${responseMap['requestId']} 不能匹配');
            }
          },
          failed: (String code, String errorMsg) {
            XLogUtils.printLog('--快麦标签打印api请求失败');
            statePage.toast('快麦标签打印api请求失败:$errorMsg');
            //阿里云日志
            XAliyunLogUtils.sendLog(
                RBAliyunLogUtils.getAliyunLogKey_Print(msg.orderNo),
                '---快麦标签打印api请求失败! msgId=${msg.msgId}, errorMsg=$errorMsg');
            //
            msgQueue?.handleFailedMessageAndUnlockTempMessageQueue(
                msg.msgId, errorMsg);
            //通知h5
            _printResult_callback_H5_or_clientSocket(
                statePage, false, '快麦标签打印api请求失败:$errorMsg', msg);
          });
    }
  }

  //处理快麦小票api响应
  static void _handleKMResponse_xiaopiao(XPageState statePage,
      Map<String, dynamic> responseMap, XBaseQueueMessage msgSrc) {
    //小票模版数据 base64转字节流
    List<int> dataByte =
        XJiamiUtils.base64ToUint8List(responseMap['data'] ?? '');

    if (RBConfigs.isShangMiDevice && RBConfigs.isUserShangMiPrint) {
      //商米内置打印
      XFlutterPluginUtils.printBytesByShangMi(dataByte);
      //通知h5
      _printResult_callback_H5_or_clientSocket(
          statePage, true, '商米内置打印', msgSrc);
    } else {
      //蓝牙小票打印机
      msgSrc.message_Uint8List = dataByte;

      XLogUtils.printLog('---蓝牙/usb/网络设备开始打印小票...');
      //阿里云日志
      XAliyunLogUtils.sendLog(
          RBAliyunLogUtils.getAliyunLogKey_Print(msgSrc.orderNo),
          '蓝牙/usb/网络设备开始打印小票...');

      //蓝牙/usb/网络设备打印
      _printWithBleSocketUSB(statePage, msgSrc, '小票');
    }
  }

  //处理快麦标签api响应
  static void _handleKMResponse_biaoqian(XPageState statePage,
      Map<String, dynamic> responseMap, XBaseQueueMessage msgSrc) {
    XLogUtils.printLog('---蓝牙/usb/网络设备开始打印标签...');
    //阿里云日志
    XAliyunLogUtils.sendLog(
        RBAliyunLogUtils.getAliyunLogKey_Print(msgSrc.orderNo),
        '蓝牙/usb/网络设备开始打印标签...');

    //小票模版数据 base64转字节流
    List<int> dataByte =
        XJiamiUtils.base64ToUint8List(responseMap['data'] ?? '');
    msgSrc.message_Uint8List = dataByte;

    //蓝牙/usb/网络设备打印
    _printWithBleSocketUSB(statePage, msgSrc, '标签');
  }

  //蓝牙/usb/网络设备打印
  static void _printWithBleSocketUSB(
      XPageState statePage, XBaseQueueMessage msgSrc, String printTagName) {
    //判断是否存在指定打印机序号(采用确定蓝牙地址方式)
    String? deviceSerialNumber = msgSrc.deviceSerialNumber;
    //hyl 2023.10.28 优化, 必定存在打印机序号,默认1,
    bool isHasAppointPrinter = false;
    //确定蓝牙地址
    for (XBaseDevice deviceItem in bluetoothPrinters) {
      //判断设备序号
      if (deviceSerialNumber == deviceItem.serialNumber) {
        List<XBaseDeviceScene>? scenes = deviceItem.scenes;
        if (scenes != null) {
          for (XBaseDeviceScene scene in scenes) {
            //判断设备场景
            if (scene == msgSrc.deviceScene) {
              //
              isHasAppointPrinter = true;
              //
              msgSrc.deviceName = deviceItem.deviceName;
              msgSrc.bluetoothAddress = deviceItem.bluetoothAddress;
              //
              XBluetoothBLEUtils.sendMsgToQueue(msgSrc);
              break;
            }
          }
        }
      }
    }

    if (isHasAppointPrinter) {
      XLogUtils.printLog("---已找到指定蓝牙打印机,$printTagName打印");
      //阿里云日志
      XAliyunLogUtils.sendLog(
          RBAliyunLogUtils.getAliyunLogKey_Print(msgSrc.orderNo),
          '---已找到指定蓝牙打印机,$printTagName打印');
      return;
    }

    //ip打印机
    for (XBaseDevice deviceItem in socketPrinters_ip) {
      //判断设备序号
      if (deviceSerialNumber == deviceItem.serialNumber) {
        List<XBaseDeviceScene>? scenes = deviceItem.scenes;
        if (scenes != null) {
          for (XBaseDeviceScene scene in scenes) {
            //判断设备场景
            if (scene == msgSrc.deviceScene) {
              //
              isHasAppointPrinter = true;
              //
              msgSrc.deviceName = deviceItem.deviceName;
              msgSrc.ip = deviceItem.ip; //"192.168.2.111";
              msgSrc.port = deviceItem.port; //9100;
              XSocketUtils.sendMsgToQueue(msgSrc);
              break;
            }
          }
        }
      }
    }

    if (isHasAppointPrinter) {
      XLogUtils.printLog("---已找到指定IP打印机,打印$printTagName");
      //阿里云日志
      XAliyunLogUtils.sendLog(
          RBAliyunLogUtils.getAliyunLogKey_Print(msgSrc.orderNo),
          '---已找到指定IP打印机,打印$printTagName');
      return;
    }

    for (XBaseDevice deviceItem in usbPrinters) {
      //判断设备序号
      if (deviceSerialNumber == deviceItem.serialNumber) {
        List<XBaseDeviceScene>? scenes = deviceItem.scenes;
        if (scenes != null) {
          for (XBaseDeviceScene scene in scenes) {
            //判断设备场景
            if (scene == msgSrc.deviceScene) {
              //
              isHasAppointPrinter = true;
              msgSrc.deviceName = deviceItem.deviceName;
              //
              XUsbUtils.sendMessage(deviceItem, msgSrc).then((bool isSuccess) {
                //打印结果通知
                _printResult_callback_H5_or_clientSocket(
                    statePage, isSuccess, deviceItem.deviceName ?? '', msgSrc);
              });
              break;
            }
          }
        }
      }
    }

    if (isHasAppointPrinter) {
      XLogUtils.printLog("---已找到指定USB打印机,打印$printTagName");
      //阿里云日志
      XAliyunLogUtils.sendLog(
          RBAliyunLogUtils.getAliyunLogKey_Print(msgSrc.orderNo),
          '---已找到指定USB打印机,打印$printTagName');
      return;
    }

    if (!isHasAppointPrinter) {
      XLogUtils.printLog("---没有找到指定$printTagName打印机");
      //阿里云日志
      XAliyunLogUtils.sendLog(
          RBAliyunLogUtils.getAliyunLogKey_Print(msgSrc.orderNo),
          '---没有找到指定$printTagName打印机');

      //打印结果通知
      _printResult_callback_H5_or_clientSocket(
          statePage, false, '没有找到指定打印机', msgSrc);
    }
  }

  //打印结果通知h5
  static void _printResult_callback_H5_or_clientSocket(XPageState statePage,
      bool isPrintSuccess, String deviceName, XBaseQueueMessage? msg) {
    dynamic kmPrintH5Id = "";
    try {
      List<dynamic>? parmList = msg?.otherParams;
      if (parmList != null) {
        if (parmList.length > 2) {
          kmPrintH5Id = parmList[2];
        }
      }
    } catch (e) {
      XLogUtils.printLog('---otherParams报错: error:$e');
    }

    if (msg != null && msg.isRemoteSocketMessage == true) {
      //通知clientSocket
      XLogUtils.printLog(
          '---打印设备:$deviceName, ${isPrintSuccess ? "打印成功" : "打印失败"},通知子设备,msg=${msg.msgId}');
      //阿里云日志
      XAliyunLogUtils.sendLog(
          RBAliyunLogUtils.getAliyunLogKey_Print(msg.orderNo),
          '---打印设备:$deviceName, ${isPrintSuccess ? "打印成功" : "打印失败"},通知子设备,kmPrintH5Id=$kmPrintH5Id, msgId=${msg.msgId}');

      msg.message_Uint8List = null;
      msg.message = null;
      msg.isRemoteSocketMessage = false;

      Map<String, dynamic> dMap = {};
      dMap['type'] = 'ServerSocketNotifyClientSocketWriteMsgResult';
      dMap['isPrintSuccess'] = isPrintSuccess;
      dMap['data'] = msg;

      XBaseQueueMessage msgSocket = XBaseQueueMessage(
          msgId: '通知子设备_${XDateUtils.getCurrentTime_ms()}',
          isServerSendToClientMessage: true,
          ip: msg.remoteIP,
          port: msg.remotePort,
          message: dMap);
      XSocketUtils.sendMsgToQueue(msgSocket);
    } else {
      //通知h5
      XLogUtils.printLog(
          '---打印设备:$deviceName, ${isPrintSuccess ? "打印成功" : "打印失败"},通知h5,kmPrintH5Id=$kmPrintH5Id');
      //阿里云日志
      XAliyunLogUtils.sendLog(
          RBAliyunLogUtils.getAliyunLogKey_Print(msg?.orderNo),
          '---打印设备:$deviceName, ${isPrintSuccess ? "打印成功" : "打印失败"},通知h5,kmPrintH5Id=$kmPrintH5Id');

      if (isPrintSuccess) {
        //打印成功
        if (statePage is MainWebViewStatePage) {
          statePage.runJSFunction(_jsFunction_notifyPrintEnd('1', kmPrintH5Id));
        }
      } else {
        //打印失败
        //statePage.toast('打印设备:$deviceName 打印失败!');
        if (statePage is MainWebViewStatePage) {
          statePage
              .runJSFunction(_jsFunction_notifyPrintEnd('-1', kmPrintH5Id));
          statePage.runJSFunction(_jsFunction_toastMessageNotifyH5(
              'printResult', '打印设备:$deviceName 打印失败!'));
        }
      }
    }
  }

  //////////////////////////////

//写入蓝牙BLE设备监听
  static XFunctionWriteMessageToBleDeviceListener?
      writeMessageToBleDeviceListener;
  static XFunctionBleDeviceConnectListener? bleDeviceConnectListener;
  //蓝牙监听
  static void _initBleDeviceListener(XPageState statePage) {
    //写入蓝牙BLE设备监听
    writeMessageToBleDeviceListener =
        (isSuccess, deviceName, deviceAddress, msg) {
      if (msg == null) {
        //
        XLogUtils.printLog('---msg=null,忽略不通知h5');
        return;
      }

      //
      _printResult_callback_H5_or_clientSocket(
          statePage, isSuccess, deviceName ?? '', msg);
    };
    bleDeviceConnectListener = (bool isConnect, String deviceAddress) {
      if (!isConnect) {
        if (statePage is MainWebViewStatePage) {
          statePage.runJSFunction(_jsFunction_toastMessageNotifyH5(
              'printerStatus', '蓝牙设备:$deviceAddress 断开连接'));
        } else {
          statePage.toast('蓝牙设备:$deviceAddress 断开连接');
        }
      }
    };

    //
    XBluetoothBLEUtils.addWriteMessageToBleDeviceListener(
        writeMessageToBleDeviceListener!);
    XBluetoothBLEUtils.addBleDeviceConnectListener(bleDeviceConnectListener!);
  }

  //
  static XFunctionReceiveSocketDeviceMessageListener?
      serverSocketDeviceReceiveMessageListener;
  static XFunctionReceiveSocketDeviceMessageListener?
      clientSocketDeviceReceiveMessageListener;
  static XFunctionWriteMessageToSocketDeviceListener?
      serverSocketWriteMessageListener;
  static XFunctionWriteMessageToSocketDeviceListener?
      clientSocketWriteMessageListener;
  static XFunctionClientSocketDeviceConnectListener?
      clientSocketDeviceConnectListener;
  //socket设备监听
  static void _initSocketDeviceListener(XPageState statePage) {
    //接收监听
    serverSocketDeviceReceiveMessageListener = (String? ip, //对方ip
        int? port, //对方端口
        String? message) {
      //服务端
      //XLogUtils.printLog('---hd服务端接收到消息: ip=$ip, message=$message');
      try {
        if (message != null && message.startsWith('{')) {
          Map<String, dynamic> socketMap = XJsonUtils.json2Map(message);

          if ('XCustomSocketData' == socketMap['XDataType']) {
            //XLogUtils.printLog('---hd主设备收到自定义socket通讯消息: ip=$ip, port=$port, message=$message');
            //
            Map<String, dynamic> xData = socketMap['XData'] ?? {};

            //
            if ('XClientSocketTestPrint' == xData['type']) {
              //测试
              statePage.toast('多端打印子设备:$ip 测试');
              XTTSUtils.speak('多端打印子设备测试');
            } else if ('XClientSocketPrint' == xData['type']) {
              //子设备发送到主设备打印
              XBaseQueueMessage? msg =
                  XBaseQueueMessage.fromJson(xData['data']);
              msg.isRemoteSocketMessage = true;
              msg.isSaveToQueueSrcMsgList = true;
              msg.remoteIP = ip;
              msg.remotePort = port ?? 10000;
              XLogUtils.printLog('---hd主设备收到子设备打印通知,msgId=${msg.msgId}');
              //阿里云日志
              XAliyunLogUtils.sendLog(
                  RBAliyunLogUtils.getAliyunLogKey_Print(msg.orderNo),
                  '---hd主设备收到子设备打印通知:$message,ip=$ip,port=$port');

              //
              msgQueue?.addNewMsgToQueueForWaitQueueAutoHandle(msg);
            }
          }
        }
      } catch (e) {
        XLogUtils.printLog(
            '---serverSocketDeviceReceiveMessageListener, error:$e');
      }
    };
    clientSocketDeviceReceiveMessageListener = (String? ip, //对方ip
        int? port, //对方端口
        String? message) {
      //客户端
      //XLogUtils.printLog('---hd客户端接收到消息: ip=$ip,port=$port,message=$message');

      try {
        if (message != null && message.startsWith('{')) {
          Map<String, dynamic> socketMap = XJsonUtils.json2Map(message);

          if ('XCustomSocketData' == socketMap['XDataType']) {
            Map<String, dynamic> xData = socketMap['XData'] ?? {};

            if ('ServerSocketNotifyClientSocketWriteMsgResult' ==
                xData['type']) {
              XLogUtils.printLog(
                  '---hd客户端收到自定义消息: ip=$ip, port=$port, message=$message');
              //子设备发送到主设备打印
              XBaseQueueMessage? msg =
                  XBaseQueueMessage.fromJson(xData['data']);
              msg.isRemoteSocketMessage = false;
              bool isPrintSuccess = xData['isPrintSuccess'];
              _printResult_callback_H5_or_clientSocket(
                  statePage, isPrintSuccess, '子设备', msg);
            }
          }
        }
      } catch (e) {
        XLogUtils.printLog(
            '---serverSocketDeviceReceiveMessageListener, error:$e');
      }
    };
    //
    XSocketUtils.addServerSocketDeviceReceiveMessageListener(
        serverSocketDeviceReceiveMessageListener);
    XSocketUtils.addClientSocketDeviceReceiveMessageListener(
        clientSocketDeviceReceiveMessageListener);

    //写入监听
    serverSocketWriteMessageListener =
        (bool isSuccess, String? ip, XBaseQueueMessage? msg) {
      //打印结果通
      XLogUtils.printLog(
          '---HD服务端写入结果:isSuccess=$isSuccess,ip=$ip,msgId=${msg?.msgId}');
      //阿里云日志
      XAliyunLogUtils.sendLog(
          RBAliyunLogUtils.getAliyunLogKey_Print(msg?.orderNo),
          '---HD服务端写入结果:isSuccess=$isSuccess,ip=$ip,msgId=${msg?.msgId}');
    };
    clientSocketWriteMessageListener =
        (bool isSuccess, String? ip, XBaseQueueMessage? msg) {
      //
      XLogUtils.printLog(
          '---HD客户端写入结果:isSuccess=$isSuccess,ip=$ip,msgId=${msg?.msgId}');
      //阿里云日志
      XAliyunLogUtils.sendLog(
          RBAliyunLogUtils.getAliyunLogKey_Print(msg?.orderNo),
          '---HD客户端写入结果:isSuccess=$isSuccess,ip=$ip,msgId=${msg?.msgId}');

      //打印结果通知
      msg?.isRemoteSocketMessage = false;
      if (!XStringUtils.isEmpty(msg?.orderNo)) {
        if (isSuccess) {
          if (isEnableServerClientSocketPrint && !isServerSocketPrinter) {
            //多端打印子设备,写入成功还需要等主设备打印完毕再通知真正成功
            return;
          }
          _printResult_callback_H5_or_clientSocket(
              statePage, isSuccess, ip ?? '', msg);
        } else {
          _printResult_callback_H5_or_clientSocket(
              statePage, isSuccess, ip ?? '', msg);
        }
      }
    };
    //
    XSocketUtils.addServerSocketDeviceWriteMessageListener(
        serverSocketWriteMessageListener);
    XSocketUtils.addClientSocketDeviceWriteMessageListener(
        clientSocketWriteMessageListener);

    clientSocketDeviceConnectListener = (
      bool isConnect,
      String? ip,
      int? port,
    ) {
      if (!isConnect) {
        if (statePage is MainWebViewStatePage) {
          statePage.runJSFunction(_jsFunction_toastMessageNotifyH5(
              'printerStatus', '网络设备:$ip 断开连接'));
        } else {
          statePage.toast('网络设备:$ip 断开连接');
        }
      }
    };
    XSocketUtils.addClientSocketDeviceConnectListener(
        clientSocketDeviceConnectListener);
  }

  // static void release(){
  //
  //   XBluetoothBLEUtils.removeWriteMessageToBleDeviceListener(writeMessageToBleDeviceListener);
  //   XBluetoothBLEUtils.removeBleDeviceConnectListener(bleDeviceConnectListener);
  //   XSocketUtils.removeServerSocketDeviceReceiveMessageListener(serverSocketDeviceReceiveMessageListener);
  //   XSocketUtils.removeClientSocketDeviceReceiveMessageListener(clientSocketDeviceReceiveMessageListener);
  //   XSocketUtils.removeServerSocketDeviceWriteMessageListener(serverSocketWriteMessageListener);
  //   XSocketUtils.removeClientSocketDeviceWriteMessageListener(clientSocketWriteMessageListener);
  //   XSocketUtils.removeClientSocketDeviceConnectListener(clientSocketDeviceConnectListener);
  //   msgQueue?.xRelease();
  //
  // }

  static String _jsFunction_notifyPrintEnd(String code, String kmPrintH5Id) {
    return "javascript:notifyPrintEnd(`$code`,`$kmPrintH5Id`)";
  }

  static String _jsFunction_toastMessageNotifyH5(String key, String message) {
    return "javascript:toastMessageNotifyH5(`$key`,`$message`)";
  }

//快麦云远程api打印//////////////////////////////////////////////////////

// String appID_kuaimai='1625638525787';
// String appSecret_kuaimai='dabef9624c4d4a318cd9843584c2ef1c';
/*
  快麦远程打印,
  sn: 设备序号  KM118MW23230050
  templateId: 模版id
  renderData: 模版动态渲染数据, json字符串
  printTimes:打印份数
   */
// void kuaimaiDeviceApiRemotePrintXiaopian({
//   required String sn,
//   required String templateId,
//   required String renderData,
//   int printTimes=1,
// }){
//
//   String url='https://cloud.kuaimai.com/api/cloud/print/escTemplatePrint';
//   Map<String,dynamic> requestMap={};
//   requestMap['appId']=appID_kuaimai;
//   requestMap['timestamp']=XDateUtils.getCurrentTime_String();
//   requestMap['sn']=sn;
//   requestMap['templateId']=templateId;
//   requestMap['renderData']=renderData;
//   requestMap['cut']=true;
//   requestMap['sign']=_getKuaimaiDeviceApiRemotePrintSign(requestMap);
//
//   XHttpUtils.request_async(
//       url: url,
//       dataJson:XJsonUtils.obj2Json(requestMap),
//       succeed: (String result, Map<String, dynamic> headers_response) {
//
//       },
//       failed: (String code, String msg) {
//
//       }
//   );
//
// }

//获得快麦签名(api远程打印)
// String _getKuaimaiDeviceApiRemotePrintSign(Map<String,dynamic> requestMap){
//   //按升序排序
//   List<String> keys=requestMap.keys.toList();
//   keys.sort();
//   StringBuffer stringBuffer=StringBuffer();
//   //
//   stringBuffer.write(appSecret_kuaimai);
//   //
//   for(String key in keys){
//     stringBuffer.write(key);
//     stringBuffer.write(requestMap[key]);
//   }
//   //
//   stringBuffer.write(appSecret_kuaimai);
//
//   //
//   String x=XJiamiUtils.strToMd5(stringBuffer.toString()).toLowerCase();
//
//   return x;
// }
}
